package com.huaxonline.sign.sdk;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * 签名工具类
 * 提供快速签名生成和验证的静态方法
 * 
 * @author zhaoshulei
 * @since 2023/9/13
 */
public class SignUtil {
    
    /**
     * 生成签名客户端
     */
    public static SignClient createClient(String appId, String secret) {
        return new SignClient(appId, secret);
    }
    
    /**
     * 生成签名客户端（指定算法）
     */
    public static SignClient createClient(String appId, String secret, SignClient.SignAlgorithm algorithm) {
        return new SignClient(appId, secret, algorithm);
    }
    
    /**
     * 生成签名客户端（完整配置）
     */
    public static SignClient createClient(String appId, String secret, SignClient.SignAlgorithm algorithm, 
                                        long timestampDisparity, boolean debugMode) {
        return new SignClient(appId, secret, algorithm, timestampDisparity, debugMode);
    }
    
    /**
     * 快速生成签名
     */
    public static String quickSign(String appId, String secret, Map<String, Object> params) {
        SignClient client = createClient(appId, secret);
        long timestamp = System.currentTimeMillis();
        String nonce = generateNonce();
        
        Map<String, Object> signParams = new TreeMap<>(params);
        signParams.put(SignClient.HEADER_TIMESTAMP, timestamp);
        signParams.put(SignClient.HEADER_NONCE, nonce);
        
        return client.generateSign(signParams);
    }
    
    /**
     * 快速生成签名（包含请求体）
     */
    public static String quickSignWithBody(String appId, String secret, Map<String, Object> params, String body) {
        SignClient client = createClient(appId, secret);
        long timestamp = System.currentTimeMillis();
        String nonce = generateNonce();
        
        Map<String, Object> signParams = new TreeMap<>(params);
        signParams.put(SignClient.HEADER_TIMESTAMP, timestamp);
        signParams.put(SignClient.HEADER_NONCE, nonce);
        
        return client.generateSignWithBody(signParams, body);
    }
    
    /**
     * 验证时间戳
     */
    public static boolean isValidTimestamp(long timestamp, long disparity) {
        long timeDiff = Math.abs(System.currentTimeMillis() - timestamp);
        return disparity == -1L || timeDiff <= disparity;
    }
    
    /**
     * 生成随机nonce
     */
    public static String generateNonce() {
        return java.util.UUID.randomUUID().toString().replace("-", "");
    }
    
    /**
     * 生成时间戳
     */
    public static long generateTimestamp() {
        return System.currentTimeMillis();
    }
    
    /**
     * 构建签名参数字符串
     */
    public static String buildSignString(Map<String, Object> params, String secret) {
        StringBuilder sb = new StringBuilder();
        sb.append("Secret=").append(secret).append("&");
        
        Map<String, Object> sortedParams = new TreeMap<>(params);
        for (Map.Entry<String, Object> entry : sortedParams.entrySet()) {
            if (entry.getValue() != null && !String.valueOf(entry.getValue()).trim().isEmpty()) {
                sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
        }
        
        if (sb.length() > 0) {
            sb.setLength(sb.length() - 1);
        }
        
        return sb.toString();
    }
    
    /**
     * 创建基本参数映射
     */
    public static Map<String, Object> createParams() {
        return new HashMap<>();
    }
    
    /**
     * 创建带时间戳和nonce的参数映射
     */
    public static Map<String, Object> createParamsWithTimestamp() {
        Map<String, Object> params = new HashMap<>();
        params.put(SignClient.HEADER_TIMESTAMP, generateTimestamp());
        params.put(SignClient.HEADER_NONCE, generateNonce());
        return params;
    }
    
    /**
     * 添加参数到映射
     */
    public static Map<String, Object> addParam(Map<String, Object> params, String key, Object value) {
        if (params == null) {
            params = new HashMap<>();
        }
        params.put(key, value);
        return params;
    }
    
    /**
     * 批量添加参数
     */
    public static Map<String, Object> addParams(Map<String, Object> params, Map<String, Object> newParams) {
        if (params == null) {
            params = new HashMap<>();
        }
        if (newParams != null) {
            params.putAll(newParams);
        }
        return params;
    }
    
    /**
     * 验证签名参数
     */
    public static boolean validateSignParams(Map<String, Object> params) {
        if (params == null) {
            return false;
        }
        
        return params.containsKey(SignClient.HEADER_TIMESTAMP) &&
               params.containsKey(SignClient.HEADER_NONCE) &&
               params.get(SignClient.HEADER_TIMESTAMP) != null &&
               params.get(SignClient.HEADER_NONCE) != null;
    }
    
    /**
     * 获取签名参数
     */
    public static SignClient.SignParams extractSignParams(Map<String, Object> params) {
        if (!validateSignParams(params)) {
            throw new IllegalArgumentException("签名参数不完整");
        }
        
        String appId = (String) params.get(SignClient.HEADER_APP_ID);
        long timestamp = Long.parseLong(String.valueOf(params.get(SignClient.HEADER_TIMESTAMP)));
        String nonce = (String) params.get(SignClient.HEADER_NONCE);
        
        return new SignClient.SignParams(appId, timestamp, nonce);
    }
    
    /**
     * 移除签名参数
     */
    public static Map<String, Object> removeSignParams(Map<String, Object> params) {
        if (params == null) {
            return new HashMap<>();
        }
        
        Map<String, Object> result = new HashMap<>(params);
        result.remove(SignClient.HEADER_APP_ID);
        result.remove(SignClient.HEADER_TIMESTAMP);
        result.remove(SignClient.HEADER_NONCE);
        result.remove(SignClient.HEADER_SIGNATURE);
        result.remove(SignClient.HEADER_HASHED_REQUEST_PAYLOAD);
        
        return result;
    }
    
    /**
     * 检查参数是否为空
     */
    public static boolean isEmpty(Map<String, Object> params) {
        return params == null || params.isEmpty();
    }
    
    /**
     * 检查参数是否不为空
     */
    public static boolean isNotEmpty(Map<String, Object> params) {
        return !isEmpty(params);
    }
    
    /**
     * 安全获取参数值
     */
    public static String getStringParam(Map<String, Object> params, String key) {
        if (params == null || key == null) {
            return null;
        }
        Object value = params.get(key);
        return value != null ? String.valueOf(value) : null;
    }
    
    /**
     * 安全获取参数值（带默认值）
     */
    public static String getStringParam(Map<String, Object> params, String key, String defaultValue) {
        String value = getStringParam(params, key);
        return value != null ? value : defaultValue;
    }
    
    /**
     * 安全获取整数参数
     */
    public static Integer getIntParam(Map<String, Object> params, String key) {
        String value = getStringParam(params, key);
        if (value == null) {
            return null;
        }
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            return null;
        }
    }
    
    /**
     * 安全获取整数参数（带默认值）
     */
    public static Integer getIntParam(Map<String, Object> params, String key, Integer defaultValue) {
        Integer value = getIntParam(params, key);
        return value != null ? value : defaultValue;
    }
    
    /**
     * 安全获取长整数参数
     */
    public static Long getLongParam(Map<String, Object> params, String key) {
        String value = getStringParam(params, key);
        if (value == null) {
            return null;
        }
        try {
            return Long.parseLong(value);
        } catch (NumberFormatException e) {
            return null;
        }
    }
    
    /**
     * 安全获取长整数参数（带默认值）
     */
    public static Long getLongParam(Map<String, Object> params, String key, Long defaultValue) {
        Long value = getLongParam(params, key);
        return value != null ? value : defaultValue;
    }
}